package com.mediacloud.app.newsmodule.activity.audio.datepicker

import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import androidx.annotation.ColorInt
import com.mediacloud.app.newsmodule.R;
import java.util.*
import kotlin.math.min

class DatePickerView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0,
) : LinearLayout(context, attrs, defStyleAttr) {

    var mCurrentYear = 0
    var mCurrentMonth = 0
    var mCurrentDay = 0
    var mCurrentHour = 0
    private var mCurrentMinute = 0
    private var isManualCurrentHourAndMinute = false

    private var mDateType: DateType? = null
    private var mYearRange: Pair<Int, Int>? = null
    private var mHighlightColor: Int? = null
    private var withUnit = false
    private var pvYear: PickerView? = null
    private var pvMonth: PickerView? = null
    private var pvDay: PickerView? = null
    private var pvHour: PickerView? = null
    private var pvMinute: PickerView? = null

    companion object {
        private const val SPACE = 5
    }

    init {
        val view = LayoutInflater.from(context).inflate(R.layout.wcy_date_picker_view, this)
        pvYear = view.findViewById(R.id.pvYear)
        pvMonth = view.findViewById(R.id.pvMonth)
        pvDay = view.findViewById(R.id.pvDay)
        pvHour = view.findViewById(R.id.pvHour)
        pvMinute = view.findViewById(R.id.pvMinute)
        orientation = HORIZONTAL
        val ta = context.obtainStyledAttributes(attrs, R.styleable.DatePickerView)
        mHighlightColor = ta.getColor(R.styleable.DatePickerView_dpvHighlightColor, Color.BLACK)
        val dateTypeId = ta.getInt(R.styleable.DatePickerView_dpvDateType, DateType.YMDHM.id)
        withUnit = ta.getBoolean(R.styleable.DatePickerView_unit, false)
        mDateType = DateType.fromId(dateTypeId)
        ta.recycle()
        initWithUnit()
        init()
    }

    private fun initWithUnit() {
        pvYear?.withUnit(withUnit)
        pvMonth?.withUnit(withUnit)
        pvDay?.withUnit(withUnit)
        pvHour?.withUnit(withUnit)
        pvMinute?.withUnit(withUnit)
    }

    private fun init() {
        val calendar = Calendar.getInstance()

        // Year
        setYearRange(mYearRange)

        // Month+
        mCurrentMonth = calendar[Calendar.MONTH] + 1
        pvMonth?.setItems(getDateItems(12, 1))
        pvMonth?.setSelectedItem(getDateForShow(mCurrentMonth, 2))

        // Day
        mCurrentDay = calendar[Calendar.DAY_OF_MONTH]
        updateDay(mCurrentYear, mCurrentMonth)

        // Hour
        if (!isManualCurrentHourAndMinute) {
            mCurrentHour = calendar[Calendar.HOUR_OF_DAY]
        }
        pvHour?.setItems(getDateItems(24, 0))
        if (mDateType != null && mDateType!!.equals(DateType.HM)){
            pvHour?.setSelectedItem(getDateForShow(mCurrentHour, 0))
        }else{
            pvHour?.setSelectedItem(getDateForShow(mCurrentHour, 2))
        }

        // Minute
        if (!isManualCurrentHourAndMinute) {
            mCurrentMinute = calendar[Calendar.MINUTE]
        }
        pvMinute?.setItems(getDateItems(60, 0))
        pvMinute?.setSelectedItem(getDateForShow(mCurrentMinute, 2))

        setDateType(mDateType)
        setHighlightColor(mHighlightColor)

        pvYear?.setOnSelect { v, item ->
            mCurrentYear = item.toInt()
            updateDay(mCurrentYear, mCurrentMonth)
        }
        pvMonth?.setOnSelect { v, item ->
            mCurrentMonth = item.toInt()
            updateDay(mCurrentYear, mCurrentMonth)
        }
        pvDay?.setOnSelect { v, item ->
            mCurrentDay = item.toInt()
        }
        pvHour?.setOnSelect { v, item ->
            mCurrentHour = item.toInt()
        }
        pvMinute?.setOnSelect { v, item ->
            mCurrentMinute = item.toInt()
        }
    }

    fun setCurrentMinute(hour: Int, minute: Int) {
        this.mCurrentHour = hour
        this.mCurrentMinute = minute
        isManualCurrentHourAndMinute = true
        init()
    }

    fun setDateType(dateType: DateType?): DatePickerView {
        mDateType = dateType
        when (mDateType) {
            DateType.HM -> {
                pvYear?.visibility = View.GONE
                pvMonth?.visibility = View.GONE
                pvDay?.visibility = View.GONE
            }
            DateType.YMD -> {
                pvHour?.visibility = View.GONE
                pvMinute?.visibility = View.GONE
            }
            DateType.YM -> {
                pvDay?.visibility = View.GONE
                pvHour?.visibility = View.GONE
                pvMinute?.visibility = View.GONE
            }
            else -> {
                (pvYear?.layoutParams as LayoutParams).weight = 1.67f
            }
        }
        return this
    }

    fun setYearRange(start: Int, end: Int): DatePickerView {
        setYearRange(Pair(start, end))
        return this
    }

    fun setYearRange(yearRange: Pair<Int, Int>?): DatePickerView {
        if (yearRange != null && (yearRange.first > yearRange.second)) {
            throw IllegalArgumentException("开始年份不能大于结束年份")
        }

        mYearRange = yearRange
        mCurrentYear = Calendar.getInstance()[Calendar.YEAR]
        val startYear = mYearRange?.first ?: mCurrentYear - SPACE
        val endYear = mYearRange?.second ?: mCurrentYear + SPACE
        val yearItems = mutableListOf<String>()
        for (i in startYear..endYear) {
            yearItems.add(i.toString())
        }
        pvYear?.setItems(yearItems)
        if (mCurrentYear !in startYear..endYear) {
            mCurrentYear = endYear
        }
        pvYear?.setSelectedItem(getDateForShow(mCurrentYear, 4))
        return this
    }

    fun withUnit(with: Boolean): DatePickerView {
        pvYear?.withUnit(with)
        pvMonth?.withUnit(with)
        pvDay?.withUnit(with)
        pvHour?.withUnit(with)
        pvMinute?.withUnit(with)
        return this
    }

    fun setHighlightColor(@ColorInt color: Int?): DatePickerView {
        mHighlightColor = color
        val highlightColor = mHighlightColor ?: Color.BLACK
        pvYear?.setHighlightColor(highlightColor)
        pvMonth?.setHighlightColor(highlightColor)
        pvDay?.setHighlightColor(highlightColor)
        pvHour?.setHighlightColor(highlightColor)
        pvMinute?.setHighlightColor(highlightColor)
        return this
    }

    fun getSelectedDate(): Long {
        return when (mDateType) {
            DateType.HM -> {
                mCurrentHour * 60 * 60 * 1000L + mCurrentMinute * 60 * 1000L
            }
            DateType.YMD -> getDateMills(
                year = mCurrentYear,
                month = mCurrentMonth,
                day = mCurrentDay,
                hour = 0,
                minute = 0
            )
            DateType.YM -> getDateMills(
                year = mCurrentYear,
                month = mCurrentMonth,
                day = 1,
                hour = 0,
                minute = 0
            )
            else -> getDateMills(
                mCurrentYear,
                mCurrentMonth,
                mCurrentDay,
                mCurrentHour,
                mCurrentMinute
            )
        }
    }

    fun getSelectedDate2(): TimeBean {
        val timeBean = TimeBean()
        timeBean.year = mCurrentYear.toString()
        timeBean.month = mCurrentMonth.toString()
        return timeBean
    }

    private fun updateDay(year: Int, month: Int) {
        val daySize = getDaySize(year, month)
        val dayItems = getDateItems(daySize, 1)
        pvDay?.setItems(dayItems)
        // fix day
        mCurrentDay = min(mCurrentDay, daySize)
        pvDay?.setSelectedItem(getDateForShow(mCurrentDay, 2))
    }

    private fun getDaySize(year: Int, month: Int): Int {
        val calendar = Calendar.getInstance()
        calendar[Calendar.YEAR] = year
        calendar[Calendar.MONTH] = month - 1
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
    }

    private fun getDateItems(size: Int, add: Int): List<String> {
        val list = mutableListOf<String>()
        for (i in 0 until size) {
            val real = i + add
            if (mDateType != null && mDateType!!.equals(DateType.HM)){
                list.add(getDateForShow(real, 0))
            }else {
                list.add(getDateForShow(real, 2))
            }
        }
        return list
    }
    private fun getDateForShow(num: Int, length: Int): String {
        var res = num.toString()
        while (res.length < length) {
            res = "0$res"
        }
        return res
    }

    private fun getDateMills(
        year: Int? = null,
        month: Int? = null,
        day: Int? = null,
        hour: Int? = null,
        minute: Int? = null,
    ): Long {
        val calendar = Calendar.getInstance()
        calendar.clear()
        if (year != null) {
            calendar.set(Calendar.YEAR, year)
        }
        if (month != null) {
            calendar.set(Calendar.MONTH, month - 1)
        }
        if (day != null) {
            calendar.set(Calendar.DAY_OF_MONTH, day)
        }
        if (hour != null) {
            calendar.set(Calendar.HOUR_OF_DAY, hour)
        }
        if (minute != null) {
            calendar.set(Calendar.MINUTE, minute)
        }
        return calendar.timeInMillis
    }
}
